<template>
  <div class="crud-table">

    <template v-if="option.dialog||option.addBtn||option.editBtn">
      <el-dialog
        :title="cacheData.dialog.title"
        :visible.sync="flags.isShowDialog"
        v-dialogDrag
        width="70%"
        :before-close="handleClose">
        <c-form ref="cform"
                :option='dialogOption'
                :initData='cacheData.init.form'
                :data='cacheData.data.form'
                @change="change"
                @submit="submit">
          <template v-slot:testName>
            <el-button @click="cacheData.data.form.slot=777">{{cacheData.data.form.slot}}</el-button>
          </template>
        </c-form>
        <span slot="footer" class="dialog-footer">
          <el-button type="primary" :loading='cacheData.loading.save' @click="onSubmit">保 存</el-button>
          <!-- <el-button @click="reBack">重 置</el-button> -->
          <el-button @click="close">关 闭</el-button>
        </span>
      </el-dialog>
    </template>


    <!-- 搜索框 -->
    <csearchbox :option="option.isSearch?searchs:searchOptions"
                @handleExport="handleExport"
                @getQuery="getQuery"
                @searchPage="searchPage"/>
                <!--可选参数 
                :textArray="textArray"
                :selectArray="selectArray"
                :timeArray="timeArray" -->

    <!-- 展示搜索值,仅供调试使用 -->
    <!-- <div v-for="(value,key,index) in query" :key="index">
      <span style="display:inline-block;width:300px">搜索框中的键名为：{{key}}</span>
      <span style="margin-left:20px">搜索框中的键值为{{value}}</span>
    </div> -->
    <slot name="ctabletitle"></slot>
    <!-- 按钮组 -->
    <div v-if="option.addBtn||option.deleteSelectBtn||option.excelBtn||option.printBtn||option.btnslot" 
         style="padding-left:10px;padding-bottom:10px;">
      <el-button v-if="option.addBtn" type="primary" @click="handleAdd">新 增</el-button>
      <el-button v-if="option.deleteSelectBtn" type="primary" plain @click="handleSomeDelete">批量删除</el-button>
      <el-button v-if="option.excelBtn" type="primary" @click="handleExport">导出Excel</el-button>
      <el-button v-if="option.printBtn" type="primary" @click="handlePrint">打 印</el-button>
      <slot name="btnslot"></slot>
    </div>

    <!-- 表格 -->
    <!-- <ctable :data="data" 
            :option="option"
            @handleView="handleView"
            @handleEdit="handleEdit"
            @handleDelete="handleDelete"
            @getSelection="getSelection"
            @getCurrentRow="getCurrentRow">
      <template v-for="(item) in option.items">
        <template v-if="item.type==='slot'" :slot="item.slotName">
          <slot :name="item.slotName">
        </slot>
        </template>
      </template>
    </ctable> -->
    <div class="ctable" :style="'height:'+(option.height?option.height+'px':'auto')">
      <el-table
        :data="data"
        :height="'100%'"
        border
        @select="checkboxSelect"
        @select-all="checkboxSelectAll"
        @selection-change="selectionChange"
        style="width: 100%">
        <!-- 默认350 -->
        <el-table-column
          v-if="option.isCheckbox"
          type="selection"
          fixed
          width="40">
        </el-table-column>
        <el-table-column
          v-if="option.isIndex"
          width="65"
          type="index"
          label="序号"
          fixed
          align='center'
          :index="indexMethod">
        </el-table-column>
        <template v-for="(item,index) in option.items">
          <el-table-column
            v-if="!item.hide"
            :key="index"
            :prop="item.key"
            :label="item.label"
            :min-width="item.min_width"
            :width="item.width"
            :align="item.align"
            :formatter="formatterColumn"
            :sortable="item.sortable"
            >
            <template slot-scope="{row,$index}">
              <slot v-if="item.type==='slot'" :name="'table_'+item.slotName" :row="row" :index="$index"></slot>
              <div v-else>{{row[item.key]}}</div>
            </template>
          </el-table-column>
        </template>
        <el-table-column 
          v-if="option.isOperation" 
          :fixed="option.operationIsFixed?option.operationIsFixed:false" 
          :label="option.operationLabel?option.operationLabel:'操作栏'" 
          :width="option.operationWidth?option.operationWidth:'250'">
          <template slot-scope="scope">
            <el-button
              v-if="option.viewBtn"
              size="mini"
              type="primary"
              @click="handleView(scope.$index, scope.row)">查 看</el-button>
            <el-button
              v-if="option.editBtn"
              size="mini"
              @click="handleEdit(scope.$index, scope.row)">编 辑</el-button>
            <el-button
              v-if="option.deleteBtn"
              size="mini"
              type="danger"
              @click="handleDelete(scope.$index, scope.row)">删 除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>


    <!-- 表格完 -->

    <slot name="ctablebottom"></slot>
    <!-- 分页 -->
    <cpagination v-if="option.isPage"
                 :page="page"
                 @handleCurrentChange="handleCurrentChange"
                 @handleSizeChange="handleSizeChange">
      <slot name="cpagination"></slot>
    </cpagination>
  </div>
</template>

<script>
// import csearchbox from '@/components/csearchbox'
// import ctable from '@/components/ctable'
// import cpagination from '@/components/cpagination'
import download from "@/api/download"
import { mapGetters } from 'vuex'

export default {
  // components:{
  //   csearchbox,//搜索框
  //   ctable,//表格
  //   cpagination,//分页
  // },
  computed: {
    ...mapGetters([
      "dictionary"              //导入字典
    ])
  },
  props:{
    //crud配置项
    option:{
      type:Object,
      default:function(){
        return null
      }
    },
    //请求
    request:{
      type:Object,
      default:function(){
        return {}
      }
    },
    //table中展示的data
    data:{
      type:Array,
      default:function(){
        return[]
      },
    },
    //分页对象
    page:{
      type:Object,
      default:function(){
        return null
      }
    },
    //搜索配置项
    searchOptions:{
      type:Object,
      default:function(){
        return {
          clearBtn:false,
          items:[]
        }
      }
    },
    //表单配置项
    dialogOption:{
      type:Object,
      default:function(){
        return {
        }
      }
    },
  },
  data(){
    return {
      flags:{
        isShowDialog:false
      },
      cacheData:{
        //存放初始化相关的
        init:{
          form:{
            // text:'文本初始化',
            // textarea:'文本框初始化',
            // date:'2021-01-13',
            // dateA: "2021-01-04",
            // dateB: "2021-01-22",
            // time: "2021-01-16 14:14:21",
            // timeA: "2021-01-09 14:21:11",
            // timeB: "2021-01-16 14:21:11",
            // select:2,
            // slot:666,
            // radio:2,
            // checkbox:[1],
            // cnumber:'12.3',
            // a:1
          },
        },
        //存放数据
        data:{
          form:{},
        },
        //存放dialog相关的临时变量
        dialog:{
          title:'',
          type:'',
        },
        //存放loading状态
        loading:{
          save:false,
        },
      },
      //查询条件集合
      query:{},

      
      //根据表格配置选项筛选出的搜索项
      searchs:{
        items:[],
      },

      //复选框选中项的集合,之后改为父传子,目前暂无需求
      selection:[],

      //搜索配置项，优先级大于textArray,selectArray,timeArray
      // searchOptions:{
      //   clearBtn:true,
      //   items:[
      //     {
      //       type:'text',
      //       key:'showText',
      //       label:'option展示用文本'
      //     },
      //     {
      //       type:'select',
      //       key:'isBind',
      //       label:'option聚合码状态',
      //       dicData:[
      //         {
      //           desc:'已绑定',
      //           val:'1'
      //         },
      //         {
      //           desc:'未绑定',
      //           val:'0'
      //         }
      //       ]
      //     },
      //     {
      //       type:'select',
      //       key:'sex',
      //       label:'性别',
      //       enumKey:'sex',
      //     },
      //     {
      //       type:'times',
      //       key:['queryStartTime','queryEndTime'],
      //       label:'option起止时间'
      //     },
      //     {
      //       type:'time',
      //       key:['queryTime'],
      //       label:'option单个时间'
      //     },
      //   ]
      // },
      // textArray:[
      //   {
      //     key:'showText',
      //     label:'展示用文本'
      //   },
      // ],
      // selectArray:[
      //   {
      //     key:'isBind',
      //     label:'聚合码状态',
      //     dicData:[
      //       {
      //         desc:'已绑定',
      //         val:'1'
      //       },
      //       {
      //         desc:'未绑定',
      //         val:'0'
      //       }
      //     ]
      //   },
      // ],
      // timeArray:[
      //   {
      //     type:'times',
      //     key:['queryStartTime','queryEndTime'],
      //     label:'起止时间'
      //   },
      //   {
      //     type:'time',
      //     key:['queryTime'],
      //     label:'单个时间'
      //   },
      // ],
    }
  },
  created(){
    this.getSearch()
    if(!this.option.isDefaultQuery){
      this.onLoad()
    }
  },
  watch:{
    'cacheData.dialog.type'(n){
      if(n==='add'){
        this.cacheData.dialog.title='新 增'
      }else if(n==='edit'){
        this.cacheData.dialog.title='编 辑'
      }
    },
    'flags.isShowDialog'(n){
      if(!n){
        this.$refs.cform.reBack()
      }else{
        if(this.$refs.cform){
          this.$refs.cform.init()
        }
      }
    },
  },
  methods:{
    //dialog提交
    onSubmit(){
      this.$refs.cform.onSubmit()
    },
    reBack(){
      this.$refs.cform.reBack()
      this.$nextTick(()=>{
        this.$refs.cform.clearValidate()
      })
    },
    close(){
      this.flags.isShowDialog=false
    },
    handleClose(done) {
      done();
    },
    //表单提交
    submit(form){
      this.cacheData.loading.save=true
      if(this.cacheData.dialog.type==='add'){
        if(this.option.submitAdd){
          this.option.submitAdd(form)
        }else{
          this.request.add(form).then((res)=>{
            this.flags.isShowDialog=false
            this.cacheData.loading.save=false
            this.$message({
              type:'success',
              message:res.msg
            })
            this.onLoad()
          }).catch(err=>{
            this.cacheData.loading.save=false
            this.$message({
              type:'error',
              message:err
            })
          })
        }
      }else{
        this.request.edit(form).then((res)=>{
          this.flags.isShowDialog=false
          this.cacheData.loading.save=false
          this.$message({
            type:'success',
            message:res.msg
          })
          this.onLoad()
        }).catch(err=>{
          this.cacheData.loading.save=false
          this.$message({
            type:'error',
            message:err
          })
        })
      }
      
    },
    change(form){
      /**
       * 加新选择时需要先将下面这段注释,否则会引起递归调用
       */
      this.cacheData.data.form=form
      this.$emit('getForm',form)
    },
    //设置data.form的某些值,不会改变其他值
    setData(obj){
      for(let key in obj){
        this.cacheData.data.form[key]=obj[key]
      }
      this.cacheData.data.form=Object.assign({},this.cacheData.data.form)
    },
    //重新设置data.form,会删除其他值
    reSetData(obj){
      this.cacheData.data.form=Object.assign({},obj)
    },

    //从option中获取搜索条件,目前支持text,time,times,select四种
    getSearch(){
      let items=this.option.items
      this.searchs.clearBtn=this.option.clearBtn
      this.searchs.items=[]
      let _this=this
      items.map(function(current,index){
        if(current.isSearch){
          let tmpObj={...current}
          if(current.type==='time'){
            tmpObj.key=[current.key]
            _this.searchs.items.push(tmpObj)
          }
          else if(current.type==='times'){
            if(index%2===0){//只对一个做处理
              let timeVal=''
              if(current.key.search('Start')!=-1){
                timeVal=current.key.replace('Start','End')
                tmpObj.key=[current.key,timeVal]
              }else{
                timeVal=current.key.replace('End','Start')
                tmpObj.key=[timeVal,current.key]
              }
              tmpObj.label='查询起止时间'
              _this.searchs.items.push(tmpObj)
            }
          }
          else if(current.type==='text'){
            _this.searchs.items.push(tmpObj)
          }
          else if(current.type==='select'){
            _this.searchs.items.push(tmpObj)
          }
        }
      })
    },

    //获取query
    getQuery(query){
      this.query={...query}
      this.$emit("getQuery",query)
    },
    //搜索按钮及清空均会调用该事件,已完成
    searchPage(){
      this.onLoad();
    },
    //加载事件,已完成
    onLoad() {
      this.$emit('onLoad',{page:this.page,query:this.query,})
    },
    
    
    //按钮组事件,配合表格组件使用,部分完成
    //选中数据均存在selection中
    //新增事件
    handleAdd(){
      this.cacheData.init.form={}
      this.$nextTick(()=>{
        this.cacheData.dialog.type='add'
        let _this=this
        if(this.$parent.beforeOpenDialog){
          this.$emit('beforeOpenDialog',{type:this.cacheData.dialog.type,done:()=>{
            _this.flags.isShowDialog=true
          }})
        }else{
          _this.flags.isShowDialog=true
        }
      })
    },
    //批量删除事件
    handleSomeDelete(){
      console.log('批量删除')
    },
    //Excel导出事件,已完成
    handleExport(){
      download.exportExcel(this.option.excelUrl,this.query,this.option.excelName+download.getDateTime()+".xlsx",this.option.excelTimeout);
    },
    //打印事件
    handlePrint(){
      console.log('print')
    },


    // 表格组件事件.列架子,未完成
    //查看事件
    handleView(index, row) {
      this.$emit('handleView',{index, row})
    },
    //编辑事件
    handleEdit(index, row) {
      let tmpObj={}
      let data=this.request.view(row,index)
      for(let i=0;i<this.dialogOption.items.length;i++){
        let el=this.dialogOption.items[i].key
        tmpObj[el]=data[el]||''
      }
      if(row.id){
        tmpObj.id=row.id
      }
      this.cacheData.init.form=tmpObj
      this.$nextTick(()=>{
        this.cacheData.dialog.type='edit'
        let _this=this
        if(this.$parent.beforeOpenDialog){
          this.$emit('beforeOpenDialog',{type:this.cacheData.dialog.type,done:()=>{
            _this.flags.isShowDialog=true
          }})
        }else{
          _this.flags.isShowDialog=true
        }
      })
    },
    //删除事件
    handleDelete(index, {id}) {
      this.$confirm(`是否删除指定数据?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.request.remove({id}).then(()=>{
          this.$message({
            type:'success',
            message:'删除成功!'
          })
          this.onLoad()
        }).catch(err=>{
          console.log(err)
          this.$message({
            type:'error',
            message:'删除失败'
          })
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '操作已取消'
        });          
      });
    },
    //获取当前勾选行
    getCurrentRow({row}){
      console.log(row)
    },
    //获取selection
    getSelection({selection}){
      this.selection=selection
    },


    // 分页组件事件开始.已封装完成
    //每页展示数量改变触发
    handleSizeChange({pageSize}) {
      this.$emit('handleSizeChange',{pageSize})
      this.onLoad()//分页改变,重新获取数据
    },
    //当前页改变事件
    handleCurrentChange({currentPage}) {
      this.$emit('handleCurrentChange',{currentPage})
      this.onLoad()//分页改变,重新获取数据
    },

    // 表格事件
    //索引的处理方法，从0开始
    indexMethod(index) {
      return index+1;
    },
    //当用户手动勾选数据行的 Checkbox 时触发的事件
    checkboxSelect(selection, row){//row当前行
      this.getSelection({selection})
      this.getCurrentRow({row})
    },
    //当用户手动勾选全选 Checkbox 时触发的事件
    checkboxSelectAll(selection){
      this.getSelection({selection})
    },
    //当选择项发生变化时会触发该事件
    selectionChange(selection){
      this.getSelection({selection})
    },
    //对字典进行筛选
    formatterColumn(row,column,cellValue,index){//当前行,当前列,当前格子值,当前行数
      let key=column.property
      let item=this.option.items[this.findIndex(key,this.option.items)]
      if(item.dicVal){
        let {dicVal}=item
        return this.findDataText(cellValue,this.dictionary[dicVal])
      }else if(item.setDicVal){
        let { setDicVal } = item
        return this.findDataText(cellValue,setDicVal)
      }else{
        return cellValue
      }
    },
    //找到同key值的对象在数组中的索引
    findIndex(key,array){
      let index=-1
      for(let i=0;i<array.length;i++){
        if(array[i].key===key){
          index=i;
          break;
        }
      }
      return index
    },
    //找到与dataCode对应的dataText
    findDataText(dataCode,array){
      let dataText=''
      for(let i=0;i<array.length;i++){
        if(dataCode===array[i].dataCode){
          dataText=array[i].dataText
          break;
        }
      }
      return dataText
    },
  },
}
</script>

<style lang='scss'>
  $boder-color:#EBEEF5;//设置表格边框颜色
  $hover-color:skyblue;//设置选中表格的颜色
  .crud-table{
    background: #fff;
    height: 100%;
    // margin: 10px 20px 30px;
    // padding: 20px;
    border-radius: 10px;
    .ctable{
      .el-table{
        width: calc(100% - 100px) !important;
        td{
          border-color: $boder-color;
        }
      }
      .el-table--border {
        border-right: 1px solid $boder-color; 
        border-bottom: 1px solid $boder-color;
        border-color: $boder-color;
        th,td{
          border-color: $boder-color;
        }
        th.gutter:last-of-type{
          border-color: $boder-color;
        }
      }

      .el-table__body tr.hover-row.current-row>td, .el-table__body tr.hover-row.el-table__row--striped.current-row>td, .el-table__body tr.hover-row.el-table__row--striped>td, .el-table__body tr.hover-row>td {
        background-color: $hover-color;
      }
    }
  }
</style>